package com.example.launcher

import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import com.example.launcher.databinding.ActivityMainBinding
import com.example.launcher.databinding.LayoutItemBinding
import java.util.*


class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private lateinit var adapter: Adapter<AppInfo, LayoutItemBinding>
    private lateinit var list: MutableList<AppInfo>
    private var item: View? = null

    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(LayoutInflater.from(this))
        setContentView(binding.root)

        binding.recyclerView.setOnTouchListener { _, event ->
            if (event.action == MotionEvent.ACTION_DOWN) {
                if (item != null) {
                    item?.clearAnimation()
                    item = null
                    return@setOnTouchListener true
                }
            }
            false
        }
        list = getAppInfo()
        adapter = Adapter<AppInfo, LayoutItemBinding>({ binding, appInfo ->
            binding.icon.setImageDrawable(appInfo.icon)
            binding.appName.text = appInfo.label
            binding.icon.setOnClickListener {
                appInfo.intent?.let { intent ->
                    startActivity(intent)
                }
            }
            addClickScale(binding.icon, 1.2f, 150)
            binding.icon.setOnLongClickListener {
                val shake: Animation = AnimationUtils.loadAnimation(this, R.anim.shake2) //加载动画资源文件
                item?.clearAnimation()
                item = binding.root
                item?.startAnimation(shake)
                if (!appInfo.isSystemApp) {
                    binding.uninstallButton.visibility = View.VISIBLE
                }
                true
            }
            binding.uninstallButton.setOnClickListener {
                val intent = Intent(Intent.ACTION_DELETE)
                intent.data = Uri.parse("package:${appInfo.packageName}")
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                startActivity(intent)
            }

        }, { inflater, parent ->
            LayoutItemBinding.inflate(inflater, parent, false)
        }).also {
            binding.recyclerView.apply {
                adapter = it
                layoutManager = GridLayoutManager(this@MainActivity, 6)
            }
        }
        adapter.dispatchUpdate(list)


        val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.Callback() {
            override fun getMovementFlags(
                recyclerView: RecyclerView,
                viewHolder: RecyclerView.ViewHolder
            ): Int {
                val dragFlags: Int
                val swipeFlags: Int
                if (recyclerView.layoutManager is GridLayoutManager) {
                    dragFlags =
                        ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
                    swipeFlags = 0
                } else {
                    dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
                    swipeFlags = 0
                }
                return makeMovementFlags(dragFlags, swipeFlags)
            }

            override fun onMove(
                recyclerView: RecyclerView,
                viewHolder: RecyclerView.ViewHolder,
                target: RecyclerView.ViewHolder
            ): Boolean {
                val fromPosition = viewHolder.adapterPosition
                val toPosition = target.adapterPosition
                if (fromPosition < toPosition) {
                    for (i in fromPosition until toPosition) {
                        Collections.swap(list, i, i + 1)
                    }
                } else {
                    for (i in fromPosition downTo toPosition + 1) {
                        Collections.swap(list, i, i - 1)
                    }
                }
                adapter.notifyItemMoved(fromPosition, toPosition)
                return true
            }

            override fun onSwiped(viewHolder: RecyclerView.ViewHolder, i: Int) {}
        })
        itemTouchHelper.attachToRecyclerView(binding.recyclerView)
    }


    @SuppressLint("QueryPermissionsNeeded", "WrongConstant")
    private fun getAppInfo(): MutableList<AppInfo> {
        val appList: MutableList<AppInfo> = mutableListOf()
        packageManager.getInstalledPackages(PackageManager.PERMISSION_GRANTED)
            .forEach { packageInfo ->
                appList.add(AppInfo().apply {
                    label = packageInfo.applicationInfo.loadLabel(packageManager).toString()
                    packageName = packageInfo.packageName
                    icon = packageInfo.applicationInfo.loadIcon(packageManager)
                    isSystemApp =
                        packageInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0
                    intent = packageManager.getLaunchIntentForPackage(packageInfo.packageName)
                })
            }

        return appList
    }


    @SuppressLint("ClickableViewAccessibility")
    fun addClickScale(view: View, scale: Float, duration: Int) {
        view.setOnTouchListener { v, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    v.animate().scaleX(scale).scaleY(scale).setDuration(duration.toLong())
                        .start()
                }
                MotionEvent.ACTION_UP -> {
                    v.animate().scaleX(1f).scaleY(1f).setDuration(duration.toLong()).start()
                    //v.performClick();
                }
                MotionEvent.ACTION_CANCEL -> {
                    v.animate().scaleX(1f).scaleY(1f).setDuration(duration.toLong()).start()
                }
            }
            false
        }
    }
}